/**
 *  tp2
 *  Author: thainh
 *  Description: 
 */

model tp2

global {
// define variables globales pour l'environnement
	int width_and_height_of_environment min:50 max:1000 <- 100;		
	
// define variables globales pour environnement pour les arbres	
	int number_of_tree max: 1000 <- 100;
	float size_of_tree max: 10.0 <- 8.0;
	int burning_range max: 50 <-2; // Dans ce range, les autre arbres est burning aussi				
			
	string image_tree_path <- '../images/arbres.png';
	int over_4m <- 0; // Pout compter les arbres qui plus grand 4m
	
	int tree_burning_time <- 500; // Apres ce temp, les arbres est mort
	int tree_propagating_time <- 100;
	float tree_propagation_probability <- 0.5 max: 1.0;
	int tree_drying_time <- 200;
	
// define variables globales pour environnement pour les pompiers
    int number_of_pompier max: 20 <- 3;
    float size_of_pompier <- 6.0;
    float speed_of_pompier <- 1.0;
    float rayon_perception max: 100.0 <- 20.0; // Dans ce range, les pompiers est combattre le feu   
    float capacity_of_pompier <- 15.0; //capacité éteindre un incendie de pompier 	 
    string image_pompier_path <- '../images/fireman_dark.gif';
    int fireman_watering_distance <- 5;
    	
// Cree des list de l'arbres et le pompier
	init{
		create tree number: number_of_tree{	// list de l'arbres
//			set size <- rnd (size_of_tree);
//			if ( size > 4 ) {
//				set over_4m <- over_4m + 1;			
//			} 				
		}
		create pompier number: number_of_pompier{ // list du pompier								
		}
	}
}

environment height:width_and_height_of_environment width:width_and_height_of_environment torus: false;

entities {

// objet l'arbres intact	
	species name:tree skills:[situated,visible] control: fsm {
		rgb color <- [0,200 + rnd (55), 0] as rgb;		
		float size <- rnd(size_of_tree)+1 as float;
		point location <- point([rnd (width_and_height_of_environment -2*size_of_tree) +size_of_tree, rnd (width_and_height_of_environment -2*size_of_tree) +size_of_tree]);
		int range <- burning_range;	
		int burn_duration <- 0;				
		geometry shape <- circle(size) simplification (0.1);
		
		reflex burning when: flip(0.001){
				do action: burning;
		}
		
		action burning {							
			create tree_burning {
				set self.color <- [255,200 + rnd (55), 0] as rgb;
				set self.size <- myself.size;
				set self.location <- myself.location;											
			}
			do action: die;													
		}
						
		aspect basic{
			draw shape: circle size: size color: color;		
		}
		aspect image{ 
			draw image: image_tree_path size: size;
		}			
	}
	
// objet l'arbres est protected
	species name:tree_protected skills:[situated,visible] control: fsm {
		rgb color <- [255,200 + rnd (55), 0] as rgb;		
		float size <- rnd(size_of_tree) as float;
		point location <- point([rnd (width_and_height_of_environment -2*size_of_tree) +size_of_tree, rnd (width_and_height_of_environment -2*size_of_tree) +size_of_tree]);
		int range <- burning_range;	
		int protected_duration <- 0;
		geometry shape <- circle(size) simplification (0.1);
		
		reflex increment_duration {
			set protected_duration <- protected_duration +1;			
			if ( protected_duration > tree_drying_time ) {
				do action: intact_tree;
			}
		}
		
		action intact_tree {
			create tree {
				set self.color <- [0,200 + rnd (55), 0] as rgb;
				set self.size <- myself.size;
				set self.location <- myself.location;											
			}
			do action: die;				
		}
					
		aspect default{
			draw shape: circle size: size color: color;		
		}
		
	}

// objet l'arbres est burning
	species name:tree_burning skills:[situated,visible] control: fsm {
		rgb color <- [255,200 + rnd (55), 0] as rgb;		
		float size <- rnd(size_of_tree) as float;
		point location <- point([rnd (width_and_height_of_environment -2*size_of_tree) +size_of_tree, rnd (width_and_height_of_environment -2*size_of_tree) +size_of_tree]);
		int range <- burning_range;	
		int burn_duration <- 0;
		geometry shape <- circle(size) simplification (0.1);	
		
		reflex increment_duration {
			set burn_duration <- burn_duration +1;			
			if ( burn_duration > tree_propagating_time ) {
				do action: burning_voisin;
			}
			if ( burn_duration > tree_burning_time ) {
				do action: dead;
			}
		}
		
		action burning_voisin {					
			let voisin <- (self neighbours_at (range) of_species tree );
			if ( flip(tree_propagation_probability) ){
				ask voisin {																	
					do action: burning;				
				}						
			}					
		}
		
		action dead {			
			create tree_dead {
				set self.color <- rgb('black');
				set self.size <- 3.0;
				set self.location <- myself.location;											
			}
			do action: die;
		}
				
		action protected {			
			create tree_protected {
				set self.color <- rgb('green');
				set self.size <- myself.size;
				set self.location <- myself.location;											
			}
			do action: die;
		}
						
		aspect default{
			draw shape: circle size: size color: color;		
		}
		
	}
	
// objet l'arbres est mort
	species name:tree_dead skills:[situated,visible] control: fsm {
		rgb color <- rgb('black');		
		float size <- 3.0;
		point location <- point([rnd (width_and_height_of_environment -2*size_of_tree) +size_of_tree, rnd (width_and_height_of_environment -2*size_of_tree) +size_of_tree]);
		int range <- burning_range;	
		int burn_duration <- 0;
		float proba_propagation <- tree_propagation_probability; // propagation de feu		
		geometry shape <- circle(size) simplification (0.1);	
		

		aspect default{
			draw shape: circle size: size color: color;		
		}		
	}	
	
// objet pompier	
	species name: pompier skills:[moving]{
		rgb color <- rgb("red");
		float size <- size_of_pompier;
		point location <- [rnd (width_and_height_of_environment - 2*size_of_pompier) +size_of_pompier, rnd (width_and_height_of_environment -2*size_of_pompier) +size_of_pompier] as point;
		float range <- rayon_perception; 
		float speed <- speed_of_pompier;		
		tree_burning but <- nil;		
		geometry shape <- circle(size_of_pompier) simplification (0.1);
						
		reflex find_but when: but = nil {		
			do action: non_but;
			let tree_burning_voir <- ( (self neighbours_at (range)) of_species tree_burning );
			ask tree_burning_voir {													
				set myself.but <- self;
			}			
		}					
		
		reflex go_but when: ( but != nil ) {
			if ( dead(but) ){
				set but <- nil;
			} else {			
				do action: a_but;																					
				// obtenir une list d'arbres qui dans la range de pompier et qui est 'burning'
				let tree_burning_arrose <- ( (self neighbours_at (fireman_watering_distance)) of_species tree_burning );
	//			let tree_burning_arrose2 <- self.location neighbours_at (fireman_watering_distance);
				let test <- self distance_to but; 						
				ask tree_burning_arrose {												
					do action: protected;
				}			
				let tree_burning_arrose2 <- agents_overlapping(self) of_species tree_burning;
				ask tree_burning_arrose2 {												
					do action: protected;
				}
				write "tree list: " + tree_burning_arrose;
				write "tree list2: " + tree_burning_arrose2;			
				write "test dis: " + test;
				write "self dis" + self; 
				write "but dis: " + but;					
				write "mut" + agents_overlapping(self);
				write "mut" + agents_inside(self);	
			}		
 		} 				
 		
 		action non_but {
 			do wander speed:speed_of_pompier amplitude: 180;
 		}	
 		
 		action a_but {
 			if ( but != nil ) {
 				do goto target: but.location speed: speed;
 				write cycle;
 				write " ---> "; 
 				write but;
 			}
 		}	
 		
		aspect image {
			draw image: image_pompier_path size: size;
			draw shape: circle color: rgb('red') size: range*2+size empty: true;
			draw shape: circle color: rgb('orange') size: fireman_watering_distance*2+size empty: true;
		}
		aspect default { 			
			draw shape: circle color: color size: size ;			
		}				
	}
}

experiment tp2 type: gui {	
// category environment	
	parameter 'Width and height of environment' var: width_and_height_of_environment category: 'environment';
//	Category arbres
	parameter 'Number of arbres' var: number_of_tree category: 'arbres';
	parameter 'Size of arbres' var: size_of_tree category: 'arbres';
	parameter 'Burning range' var: burning_range category: 'arbres';
	parameter 'Tree burning time' var: tree_burning_time category: 'arbres';
	parameter 'Propagation de feu' var: tree_propagation_probability category: 'arbres'; 
	
//	Category pompier
	parameter 'Number of pompier' var: number_of_pompier category: 'pompier';
	parameter 'Size of pompier' var: size_of_pompier category: 'pompier'; 	
	parameter 'Range of pompier' var: rayon_perception category: 'pompier';
	parameter 'Capacity of pompier' var: capacity_of_pompier category: 'pompier';
		
	output{
		inspect name: 'Species' type: species;
		inspect name: 'Agent' type: agent;
		display tree_distribution refresh_every: 1 {
			chart td_diagram type:pie{
				data under_4m value:length (list (tree) where (each.size < 4) );
				data over_7m value:length (list (tree) where (each.size > 7) );
				data bettwen_4m_7m value:length (list (tree) where (each.size >= 4 and each.size <= 7) );								 				
			}
		}						
		display Forest refresh_every: 1  {
			image name:'background' file:'../images/soil.jpg';
			species tree aspect: basic;
			species tree_burning;
			species tree_protected;
			species tree_dead;
			species pompier aspect: image;			
		}
		monitor over_4m value: over_4m refresh_every: 1 ;	
	}
}

